package com.lijiajia.cloud.authserver.security.rememberme;

import com.lijiajia.cloud.authserver.pojo.mongodb.PersistentLogin;
import com.lijiajia.cloud.common.core.Constants;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.security.web.authentication.rememberme.PersistentRememberMeToken;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Date;

/**
 * 基于mongodb的持久登录令牌库实现
 *
 * @author lijiajia
 * @since 2019-04-30
 */
@Service
public class MongoPersistentTokenRepository implements PersistentTokenRepository {
	private final MongoTemplate mongoTemplate;

	public MongoPersistentTokenRepository(MongoTemplate mongoTemplate) {
		this.mongoTemplate = mongoTemplate;
	}

	@Override
	public void createNewToken(PersistentRememberMeToken token) {
		PersistentLogin persistentLogin = new PersistentLogin()
			.setSeries(token.getSeries())
			.setUsername(token.getUsername())
			.setToken(token.getTokenValue())
			.setLastUsed(LocalDateTime.ofInstant(token.getDate().toInstant(), Constants.DEFAULT_ZONE));
		mongoTemplate.save(persistentLogin);
	}

	@Override
	public void updateToken(String series, String tokenValue, Date lastUsed) {
		Query query = Query.query(Criteria.where(PersistentLogin.SERIES).is(series));

		Update update = Update.update(PersistentLogin.TOKEN, tokenValue)
			.set(PersistentLogin.LAST_USED, LocalDateTime.ofInstant(lastUsed.toInstant(), Constants.DEFAULT_ZONE_OFFSET));
		mongoTemplate.updateFirst(query, update, PersistentLogin.class);
	}

	@Override
	public PersistentRememberMeToken getTokenForSeries(String seriesId) {
		Query query = Query.query(Criteria.where(PersistentLogin.SERIES).is(seriesId));
		PersistentLogin persistentLogin = mongoTemplate.findOne(query, PersistentLogin.class);
		if (persistentLogin != null) {
			return new PersistentRememberMeToken(
				persistentLogin.getUsername(),
				persistentLogin.getSeries(),
				persistentLogin.getToken(),
				Date.from(persistentLogin.getLastUsed().toInstant(Constants.DEFAULT_ZONE_OFFSET))
			);
		}
		return null;
	}

	@Override
	public void removeUserTokens(String username) {
		Query query = Query.query(Criteria.where(PersistentLogin.USERNAME).is(username));
		mongoTemplate.remove(query, PersistentLogin.class);
	}
}
